tree grammar Reduce;
options {
    tokenVocab=VecMath;
    ASTLabelType=CommonTree;
    output=AST;
    filter=true;
    backtrack=true;
}

bottomup
    : xPlusx
    | multBy2
    | combineShifts
    ;

xPlusx: ^('+' i=INT j=INT {$i.int==$j.int}?) -> ^(MULT["*"] INT["2"] $j);

multBy2
    : ^('*' x=INT {$x.int==2}? y=.) -> ^(SHIFT["<<"] $y INT["1"])
    | ^('*' a=. b=INT {$b.int==2}?) -> ^(SHIFT["<<"] $a INT["1"])
    ;

combineShifts
    : ^(SHIFT ^(SHIFT e=. n=INT) m=INT) -> ^(SHIFT["<<"] $e INT[String.valueOf($n.int+$m.int)]);